//Name: Abstract Enemy
//Author:Max Charnock
//Last Updated: 15/05/2014
//Purpose: abstract enemy class which is inherited all enemies

#pragma once

#include "MathHelper.h"
#include "Globals.h"		// For the correct path files
#include "d3dUtil.h"		// Direct3D stuff
#include "StaticModel.h"
#include "GraphicsInterface.h"
#include "CollisionManager.h"
#include "Terrain.h"
#include "Behaviours.h"
#include "AbstractState.h"
#include "Player.h"

//the speeds of enemies
#define HEAVY_ENEMY_SPEED 6.0f
#define NORMAL_ENEMY_SPEED 8.0f
#define FAST_ENEMY_SPEED 10.0f
#define ALERT_ENEMY_SPEED 10.0f

//the damage enemies can inflict
#define HEAVY_ENEMY_DAMAGE 3
#define NORMAL_ENEMY_DAMAGE 2
#define FAST_ENEMY_DAMAGE 1
#define ALERT_ENEMY_DAMAGE 1

//the aggression radius for enemies
#define HEAVY_ENEMY_AGGRO 20.f
#define NORMAL_ENEMY_AGGRO 30.f
#define FAST_ENEMY_AGGRO 40.f
#define ALERT_ENEMY_AGGRO 40.f

//the distance enmies will chase the player for
#define HEAVY_ENEMY_CHASE 200.0f
#define NORMAL_ENEMY_CHASE 300.0f
#define FAST_ENEMY_CHASE 400.0f
#define ALERT_ENEMY_CHASE 400.0f

//health of enemies
#define HEAVY_ENEMY_HEALTH 3
#define NORMAL_ENEMY_HEALTH 2
#define FAST_ENEMY_HEALTH 1
#define ALERT_ENEMY_HEALTH 1

//time a enemy is invunerable for
#define ENEMY_INVUL_TIME 2.0f

enum EnemyType {FAST,HEAVY,NORMAL,ALERTER};

class AbstractEnemy
{
protected:

	//bool used to determine whether enemy is alive
	bool IsAlive;

	//hitbox used for collision detection
	AABB HitBox;

	// Pointer for the enemies model data - We load one from file. 
	StaticModel* EnemyModel;

	// Pointer to the terrain (so we can get the height)
	Terrain* terrain;

	//damage the enemy can issue
	int Damage;

	int Health;

	bool Invunerable;
	float InvunTimer;

	//type of enemy
	EnemyType Type;

	//distance the enemy will chase the player for
	float ChaseDistance;

	//spehere used to determine when the enemy will notice the player
	float AggroRadius; 

	//patrol the enemy will follow
	std::vector<XMFLOAT3> Patrol;

	//target the enmy will head towards
	XMFLOAT3 Target;

	//behaviours the enemy will follow
	Behaviours EnemyBehaviours;

	//pointer to current state
	State<AbstractEnemy>* pCurrentState;

	//pointer to player
	Player* pPlayer;

	//velocity the enemy is traveling at
	XMFLOAT3 Velocity;


public:

	AbstractEnemy();
	virtual ~AbstractEnemy();

	//gets and sets for enemy type
	EnemyType GetType();
	void SetType(EnemyType type);

	//gets and sets for enemy damage
	int GetDamage();
	void SetDamage(int damage);

	//gets and sets for chase distance
	float GetChaseDistance();
	void SetChaseDistance(float distance);

	//gets and sets for aggro radius
	float GetAggroRadius();
	void SetAggroRadius(float radius);

	//renders enemy model
	void AddToBatch(GraphicsInterface* gi);

	//virtual funtion used to set enemies intial values such as model, positon and damage values.
	virtual void Intialise(ID3D11Device* device, 
							XMFLOAT3 position, 
							XMFLOAT3 rotation, 
							XMFLOAT3 scale,
							Terrain* gameTerrain,
							Player* player)=0;

	//virtual fucntion used to update the enemies values
	virtual void Update(float delta)=0;

	//returns hitbox for collision detection
	AABB GetHitBox();

	//returns whether a enemy is alive
	bool GetIsAlive();

	//sets whether the enmy is alive or not
	void SetIsAlive(bool alive);

	//set patrol paths
	void SetPatrol(std::vector<XMFLOAT3> patrol);
	std::vector<XMFLOAT3> GetPatrol();

	void SetTarget(XMFLOAT3 target);
	XMFLOAT3 GetTarget();

	Behaviours* GetBehaviours();

	// used to change between states
	void ChangeState(State<AbstractEnemy>* pNewState);

	XMFLOAT3 GetPlayerPos();

	XMFLOAT3 GetVelocity();
	void SetVelocity(XMFLOAT3 velocity);

	XMFLOAT3 GetPosition();

	int GetHealth();
	void SetHealth(int health);
	
	
	bool GetInvunerable();
	void SetInvunerable(bool invun);
};